From ac8f25b4e562c7b694be38454fa7cf8521fd1301 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 3 Apr 2003 21:21:26 +0000 Subject: [PATCH] bitkeeper revision 1.160.1.2 (3e8ca5d6NuIwQ-85rqA_rDQ3WcxL2A) mm.h, xen_block.c, memory.c: Changed the page-typing fix around; it at least _looks_ a bit more generic now :-) --- xen/common/memory.c | 8 ++++++-- xen/drivers/block/xen_block.c | 8 ++++---- xen/include/xeno/mm.h | 18 +++++++++--------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/xen/common/memory.c b/xen/common/memory.c index e6139b00e5..c39b1ae862 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -441,7 +441,7 @@ static int get_page(unsigned long page_nr, int writeable) page->flags &= ~PG_type_mask; page->flags |= PGT_writeable_page; } - page->flags &= ~PG_noflush; + page->flags |= PG_need_flush; get_page_type(page); } @@ -500,9 +500,13 @@ static void put_page(unsigned long page_nr, int writeable) ASSERT(DOMAIN_OKAY(page->flags)); ASSERT((!writeable) || ((page_type_count(page) != 0) && - ((page->flags & PG_type_mask) == PGT_writeable_page))); + ((page->flags & PG_type_mask) == PGT_writeable_page) && + ((page->flags & PG_need_flush) == PG_need_flush))); if ( writeable && (put_page_type(page) == 0) ) + { tlb_flush[smp_processor_id()] = 1; + page->flags &= ~PG_need_flush; + } put_page_tot(page); } diff --git a/xen/drivers/block/xen_block.c b/xen/drivers/block/xen_block.c index 8901ee59fb..441ee09028 100644 --- a/xen/drivers/block/xen_block.c +++ b/xen/drivers/block/xen_block.c @@ -306,9 +306,9 @@ static void __lock_buffer(unsigned long buffer, { if ( page->type_count == 0 ) { - page->flags &= ~PG_type_mask; + page->flags &= ~(PG_type_mask | PG_need_flush); /* NB. This ref alone won't cause a TLB flush. */ - page->flags |= PGT_writeable_page | PG_noflush; + page->flags |= PGT_writeable_page; } get_page_type(page); } @@ -332,11 +332,11 @@ static void unlock_buffer(struct task_struct *p, page = frame_table + pfn; if ( writeable_buffer && (put_page_type(page) == 0) && - !(page->flags & PG_noflush) ) + (page->flags & PG_need_flush) ) { __flush_tlb(); + page->flags &= ~PG_need_flush; } - page->flags &= ~PG_noflush; put_page_tot(page); } spin_unlock_irqrestore(&p->page_lock, flags); diff --git a/xen/include/xeno/mm.h b/xen/include/xeno/mm.h index 6a2e2e9396..f71255f971 100644 --- a/xen/include/xeno/mm.h +++ b/xen/include/xeno/mm.h @@ -98,17 +98,17 @@ typedef struct pfn_info { #define PGT_net_rx_buf (8<<24) /* this page has been pirated by the net code. */ /* - * This bit is sometimes set by Xen when it holds a writeable reference to a - * page that shouldn't cause a TLB flush when it is dropped. For example, a - * disk write to a page with initial type_count == 0, which returns to 0 after - * the I/O. In this case, we'd normally flush the TLB because a writeable page - * has just lost its mutually-exclusive type. But this isn't necessary here - * because the writeable reference never made it into user-accessible TLB - * (didn't make it into TLB at all, in fact). + * This bit indicates that the TLB must be flushed when the type count of this + * frame drops to zero. This is needed on current x86 processors only for + * frames which have guestos-accessible writeable mappings. In this case we must + * prevent stale TLB entries allowing the frame to be written if it used for a + * page table, for example. * - * This bit is obviously nuked in a few places, for safety. + * We have this bit because the writeable type is actually also used to pin a page + * when it is used as a disk read buffer. This doesn't require a TLB flush because + * the frame never has a mapping in the TLB. */ -#define PG_noflush (1<<28) +#define PG_need_flush (1<<28) #define PageSlab(page) test_bit(PG_slab, &(page)->flags) #define PageSetSlab(page) set_bit(PG_slab, &(page)->flags) -- 2.30.2